package com.it.you.common.aop;

import com.it.you.entity.pojo.TbLog;
import com.it.you.service.log.LogService;
import com.it.you.common.utils.Conv;
import com.it.you.common.utils.IpAddressUtil;
import com.it.you.common.utils.JacksonUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

/**
 * 切面工具类
 */
@Component
@Aspect
public class LogAopAspect {

    @Autowired
    private LogService logService;

    @Around("@annotation(com.it.you.common.aop.LogAnno)")
    public void aroundAdvice(ProceedingJoinPoint joinPoint) throws Exception {
        //保存日志
        TbLog tbLog = new TbLog();
        //从切面织入点处通过反射机制获取织入点的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在方法
        Method method = signature.getMethod();

        //获取操作
        LogAnno operation = method.getAnnotation(LogAnno.class);
        if (operation != null) {
            String value = operation.operateType();
            tbLog.setOperation(value);
        }
        //获取请求的类名
        String className = joinPoint.getTarget().getClass().getName();
        //获取请求的方法名
        String methodName = method.getName();
        tbLog.setMethod(className + "-" + methodName);
        //请求参数
        Object[] args = joinPoint.getArgs();
        //获取请求参数中携带的用户id或者username存入日志库中
        String s = JacksonUtil.obj2Json(args);
        String[] split = s.split("\\[");
        String[] split1 = split[1].split("\\]");
        Map<String, Object> map = JacksonUtil.json2Map(split1[0]);
        if (map.get("id") != null) {
            tbLog.setUserId(Conv.NL(map.get("id")));
        }
        if (map.get("userName") != null) {
            tbLog.setUserName(Conv.NS(map.get("userName")));
        }

        //将参数所在的数组转换成json
        String params = null;
        try {
            params = JacksonUtil.obj2Json(args);
        } catch (Exception e) {
            e.printStackTrace();
        }
        tbLog.setParams(params);

        //请求时间
        tbLog.setCreateDate(new Date());

        Object proceed = null;
        try {
            proceed = joinPoint.proceed();
            tbLog.setOperateResult("请求成功");
        } catch (Throwable e) {
            e.printStackTrace();
            tbLog.setOperateResult("请求失败");
            tbLog.setAbnormality(e.toString());
        }

        //获取用户ip
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        tbLog.setIp(IpAddressUtil.getIpAddress(request));
        //保存操作日志
        logService.save(tbLog);
    }
}
